using System;
using System.IO;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Text;
using System.Text.RegularExpressions;
using ExifLib;

namespace Rename
{
	public class MainForm : System.Windows.Forms.Form
	{
		#region WinForms Plumbing;

		internal System.Windows.Forms.ListView ctrl_FileList;
		internal System.Windows.Forms.ColumnHeader FileList_Col_Name;
		internal System.Windows.Forms.ColumnHeader FileList_Col_Size;
		internal System.Windows.Forms.ColumnHeader FileList_Col_DateTaken;
        internal System.Windows.Forms.ColumnHeader FileList_Col_FullPath;
		private System.Windows.Forms.TextBox ctrl_PatternSequence;
		private System.Windows.Forms.Button ctrl_RenameButton;
		private System.Windows.Forms.Button ctrl_ClearButton;
		private System.Windows.Forms.StatusBar ctrl_Status;
		private System.Windows.Forms.StatusBarPanel statusBarPanel1;
        private System.Windows.Forms.StatusBarPanel statusBarPanel2;
        private Label ctrl_Out;
		private System.ComponentModel.Container components = null;
        private Button ctrl_CleanButton;
        private ListViewColumnSorter ColumnSorter = new ListViewColumnSorter();

        public MainForm()
		{
            // Create an instance of a ListView column sorter and assign it 
            // to the ListView control.
			InitializeComponent();
            this.ctrl_FileList.ListViewItemSorter = ColumnSorter;
        }

        protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
        private void InitializeComponent()
		{
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
            this.ctrl_FileList = new System.Windows.Forms.ListView();
            this.FileList_Col_Name = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
            this.FileList_Col_Size = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
            this.FileList_Col_DateTaken = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
            this.FileList_Col_FullPath = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
            this.ctrl_PatternSequence = new System.Windows.Forms.TextBox();
            this.ctrl_RenameButton = new System.Windows.Forms.Button();
            this.ctrl_ClearButton = new System.Windows.Forms.Button();
            this.ctrl_Status = new System.Windows.Forms.StatusBar();
            this.statusBarPanel1 = new System.Windows.Forms.StatusBarPanel();
            this.statusBarPanel2 = new System.Windows.Forms.StatusBarPanel();
            this.ctrl_Out = new System.Windows.Forms.Label();
            this.ctrl_CleanButton = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).BeginInit();
            this.SuspendLayout();
            // 
            // ctrl_FileList
            // 
            this.ctrl_FileList.AllowDrop = true;
            this.ctrl_FileList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ctrl_FileList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.FileList_Col_Name,
            this.FileList_Col_Size,
            this.FileList_Col_DateTaken,
            this.FileList_Col_FullPath});
            this.ctrl_FileList.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ctrl_FileList.FullRowSelect = true;
            this.ctrl_FileList.Location = new System.Drawing.Point(10, 10);
            this.ctrl_FileList.Name = "ctrl_FileList";
            this.ctrl_FileList.Size = new System.Drawing.Size(775, 300);
            this.ctrl_FileList.Sorting = System.Windows.Forms.SortOrder.Ascending;
            this.ctrl_FileList.TabIndex = 4;
            this.ctrl_FileList.UseCompatibleStateImageBehavior = false;
            this.ctrl_FileList.View = System.Windows.Forms.View.Details;
            this.ctrl_FileList.DragDrop += new System.Windows.Forms.DragEventHandler(this.ctrl_FileList_DragDrop);
            this.ctrl_FileList.DragEnter += new System.Windows.Forms.DragEventHandler(this.ctrl_FileList_DragEnter);
            // 
            // FileList_Col_Name
            // 
            this.FileList_Col_Name.Text = "Name";
            this.FileList_Col_Name.Width = 160;
            // 
            // FileList_Col_Size
            // 
            this.FileList_Col_Size.Text = "Size";
            this.FileList_Col_Size.Width = 100;
            // 
            // FileList_Col_DateTaken
            // 
            this.FileList_Col_DateTaken.Text = "Date Taken";
            this.FileList_Col_DateTaken.Width = 150;
            // 
            // FileList_Col_FullPath
            // 
            this.FileList_Col_FullPath.Text = "Path";
            this.FileList_Col_FullPath.Width = 166;
            // 
            // ctrl_PatternSequence
            // 
            this.ctrl_PatternSequence.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.ctrl_PatternSequence.Location = new System.Drawing.Point(12, 316);
            this.ctrl_PatternSequence.Name = "ctrl_PatternSequence";
            this.ctrl_PatternSequence.Size = new System.Drawing.Size(24, 22);
            this.ctrl_PatternSequence.TabIndex = 2;
            this.ctrl_PatternSequence.Text = "1";
            this.ctrl_PatternSequence.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.ctrl_PatternSequence.TextChanged += new System.EventHandler(this.ctrl_PatternSequence_TextChanged);
            // 
            // ctrl_RenameButton
            // 
            this.ctrl_RenameButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.ctrl_RenameButton.Enabled = false;
            this.ctrl_RenameButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.ctrl_RenameButton.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ctrl_RenameButton.Location = new System.Drawing.Point(42, 316);
            this.ctrl_RenameButton.Name = "ctrl_RenameButton";
            this.ctrl_RenameButton.Size = new System.Drawing.Size(75, 24);
            this.ctrl_RenameButton.TabIndex = 3;
            this.ctrl_RenameButton.Text = "Rename";
            this.ctrl_RenameButton.UseVisualStyleBackColor = true;
            this.ctrl_RenameButton.Click += new System.EventHandler(this.ctrl_RenameButton_Click);
            // 
            // ctrl_ClearButton
            // 
            this.ctrl_ClearButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.ctrl_ClearButton.Enabled = false;
            this.ctrl_ClearButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.ctrl_ClearButton.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ctrl_ClearButton.Location = new System.Drawing.Point(204, 316);
            this.ctrl_ClearButton.Name = "ctrl_ClearButton";
            this.ctrl_ClearButton.Size = new System.Drawing.Size(75, 24);
            this.ctrl_ClearButton.TabIndex = 5;
            this.ctrl_ClearButton.Text = "Clear";
            this.ctrl_ClearButton.Click += new System.EventHandler(this.ctrl_ClearButton_Click);
            // 
            // ctrl_Status
            // 
            this.ctrl_Status.Location = new System.Drawing.Point(0, 350);
            this.ctrl_Status.Name = "ctrl_Status";
            this.ctrl_Status.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
            this.statusBarPanel1,
            this.statusBarPanel2});
            this.ctrl_Status.ShowPanels = true;
            this.ctrl_Status.Size = new System.Drawing.Size(794, 22);
            this.ctrl_Status.SizingGrip = false;
            this.ctrl_Status.TabIndex = 6;
            // 
            // statusBarPanel1
            // 
            this.statusBarPanel1.Name = "statusBarPanel1";
            this.statusBarPanel1.Width = 755;
            // 
            // statusBarPanel2
            // 
            this.statusBarPanel2.Alignment = System.Windows.Forms.HorizontalAlignment.Center;
            this.statusBarPanel2.Name = "statusBarPanel2";
            this.statusBarPanel2.Width = 37;
            // 
            // ctrl_Out
            // 
            this.ctrl_Out.AutoSize = true;
            this.ctrl_Out.Location = new System.Drawing.Point(721, 322);
            this.ctrl_Out.Name = "ctrl_Out";
            this.ctrl_Out.Size = new System.Drawing.Size(13, 13);
            this.ctrl_Out.TabIndex = 7;
            this.ctrl_Out.Text = "0";
            this.ctrl_Out.Visible = false;
            // 
            // ctrl_CleanButton
            // 
            this.ctrl_CleanButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.ctrl_CleanButton.Enabled = false;
            this.ctrl_CleanButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.ctrl_CleanButton.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.ctrl_CleanButton.Location = new System.Drawing.Point(123, 316);
            this.ctrl_CleanButton.Name = "ctrl_CleanButton";
            this.ctrl_CleanButton.Size = new System.Drawing.Size(75, 24);
            this.ctrl_CleanButton.TabIndex = 3;
            this.ctrl_CleanButton.Text = "Clean";
            this.ctrl_CleanButton.UseVisualStyleBackColor = true;
            this.ctrl_CleanButton.Click += new System.EventHandler(this.ctrl_CleanButton_Click);
            // 
            // MainForm
            // 
            this.AccessibleDescription = "";
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 15);
            this.ClientSize = new System.Drawing.Size(794, 372);
            this.Controls.Add(this.ctrl_Out);
            this.Controls.Add(this.ctrl_Status);
            this.Controls.Add(this.ctrl_ClearButton);
            this.Controls.Add(this.ctrl_CleanButton);
            this.Controls.Add(this.ctrl_RenameButton);
            this.Controls.Add(this.ctrl_PatternSequence);
            this.Controls.Add(this.ctrl_FileList);
            this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.Name = "MainForm";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Photo Rename";
            this.Load += new System.EventHandler(this.MainForm_Load);
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		[STAThread]
		#endregion
		
		static void Main()
		{
			Application.Run(new MainForm());
		}
        
        private void MainForm_Load(object sender, System.EventArgs e)
        {
            ctrl_FileList.Items.Clear();
            RefreshAppStatus();
            ctrl_Status.Panels[0].Text = " Ready to work. Drag files into the box above to rename.";
        }
        private void ctrl_FileList_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
        {
            DateTime StartTime = DateTime.Now;
            string[] Files = (string[])e.Data.GetData(DataFormats.FileDrop);
            FileInfo File;

            foreach (string FilePath in Files)
            {
                File = new FileInfo(FilePath);

                if (!FileInList(File.Name))
                {
                    AddFileToList(File.Name, File.Length.ToString(), GetDatePictureTaken(FilePath).ToString("MMMM d, yyyy"), FilePath);
                }
            }
            
            // sort the listview by date taken (column 2)
            ColumnSorter.SortColumn = 2;
            ColumnSorter.Order = SortOrder.Ascending;
            ctrl_FileList.Sort();
            
            RefreshAppStatus();
            ctrl_Out.Text = DateTime.Now.Subtract(StartTime).ToString();
        }
        private void ctrl_FileList_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }
        private void ctrl_RenameButton_Click(object sender, System.EventArgs e)
        {
            // handle the rename button click event
            RenameFiles();
        }
        private void ctrl_PatternBody_TextChanged(object sender, System.EventArgs e)
        {
            RefreshAppStatus();
        }
        private void ctrl_PatternSequence_TextChanged(object sender, System.EventArgs e)
        {
            RefreshAppStatus();
        }
        private void ctrl_ClearButton_Click(object sender, System.EventArgs e)
        {
            ctrl_FileList.Items.Clear();
            RefreshAppStatus();
        }
        private void ctrl_CleanButton_Click(object sender, EventArgs e)
        {
            CleanFiles();
        }

        private void RenameFiles()
        {
            // loop through the files in the list and rename them
            int BaseSequence = int.Parse(ctrl_PatternSequence.Text);
            int Sequence = BaseSequence;
            string WorkingDate = "1/1/1900";

            foreach (ListViewItem Item in ctrl_FileList.Items)
            {
                if (WorkingDate != Item.SubItems[2].Text)
                {
                    // if the working date changes, reset the sequence
                    Sequence = BaseSequence;
                }

                string SrcFileName = Item.SubItems[3].Text;
                string TgtFileName = Item.SubItems[2].Text + " - " + PadStringZero(Sequence.ToString(), 3);

                RenameFile(SrcFileName, TgtFileName);

                // increment the current sequence value, and update the working date
                Sequence++;
                WorkingDate = Item.SubItems[2].Text;
            }

            // reset the form fields and update status
            ctrl_PatternSequence.Text = "1";
            ctrl_FileList.Items.Clear();
            RefreshAppStatus();
            ctrl_Status.Panels[0].Text = " Rename completed.";
        }
        private void CleanFiles()
        {
            // loop through the files in the list and scrub the file names before renaming

            int Sequence = 1;

            foreach (ListViewItem Item in ctrl_FileList.Items)
            {
                string SrcFileName = Item.SubItems[3].Text;
                string TgtFileName = "PHOTORENAME_CLEAN_" + PadStringZero(Sequence.ToString(), 3);
                RenameFile(SrcFileName, TgtFileName);
                Sequence++;
            }

            // reset the form fields and update status
            ctrl_PatternSequence.Text = "1";
            ctrl_FileList.Items.Clear();
            RefreshAppStatus();
            ctrl_Status.Panels[0].Text = " Rename completed.";
        }
        private bool FileInList(string FileName)
		{
			foreach (ListViewItem Item in ctrl_FileList.Items)
			{
				if (Item.Text == FileName)
				{
					return true;
				}
			}
			return false;
		}
        private string FormatFileSize(string FileSize)
		{
			FileSize = (int.Parse(FileSize) / 1000).ToString() + " KB";
			return FileSize;
		}
        private bool ReadyToRename()
		{
			try
			{
				//confirm that the sequence is an integer
				int.Parse(ctrl_PatternSequence.Text);
				
				//confirm the file list
				if (ctrl_FileList.Items.Count == 0)
				{
					return false;
				}
				return true;
			}
			catch
			{
				return false;
			}
		}
        private void RefreshAppStatus()
		{
			// check and set the rename button
			if (ReadyToRename())
			{
				ctrl_RenameButton.Enabled = true;
                ctrl_CleanButton.Enabled = true;
                ctrl_ClearButton.Enabled = true;
            }
			else
			{
				ctrl_Status.Panels[0].Text = "";
                ctrl_RenameButton.Enabled = false;
                ctrl_CleanButton.Enabled = false;
                ctrl_ClearButton.Enabled = false;
            }

			// adjust the status bar
			ctrl_Status.Panels[1].Text = ctrl_FileList.Items.Count.ToString();
		}
        private string CleanFileName(string FileName)
		{
			FileName = FileName.Replace("\\", "");
			FileName = FileName.Replace("/", "");
			FileName = FileName.Replace("|", "");
			FileName = FileName.Replace("\"", "");
			FileName = FileName.Replace("<", "");
			FileName = FileName.Replace(">", "");
			FileName = FileName.Replace("?", "");
			return FileName;
		}
        private string PadStringZero(string String, int TargetLength)
		{
			while (String.Length < TargetLength)
			{
				String = "0" + String;
			}
			return String;
		}
        private void AddFileToList(string FileName, string FileSize, string FileDateTaken, string FileFullPath)
		{
			ctrl_FileList.BeginUpdate();
			ListViewItem Item = new ListViewItem(FileName);
			Item.SubItems.Add(FormatFileSize(FileSize));
			Item.SubItems.Add(FileDateTaken);
			Item.SubItems.Add(FileFullPath);
			ctrl_FileList.Items.Add(Item);
			ctrl_FileList.EndUpdate();
		}
        private void RenameFile(string ExistingFileName, string NewFileName)
		{
            String Target = String.Empty;
            try
			{
				FileInfo File = new FileInfo(ExistingFileName);
			
				if (File.Exists)
				{
                    Target = File.DirectoryName + "\\" + CleanFileName(NewFileName) + File.Extension;
					File.MoveTo(Target);
				}
			}
			catch(Exception Ex)
			{
                MessageBox.Show(Ex.Message);
			}
		}
        private DateTime GetDatePictureTaken(String FilePath)
        {
            ExifReader EXR = new ExifReader(FilePath);
            DateTime DatePictureTaken;

            if (EXR.GetTagValue<DateTime>(ExifTags.DateTimeDigitized, out DatePictureTaken))
            {
                // Do whatever is required with the extracted information
                EXR.Dispose();
                return DatePictureTaken;
            }
            else
            {
                EXR.Dispose();
                return DateTime.Parse("1/1/1900");
            }
        }

    }
}
